import fs from "fs";
import path from "path";
import { exit } from "process";
import md5 from "./md5"

export default class unpack{
    /**
     * 解析出这个打包文件
     * @param {String} filePath 
     * @returns 
     */
    static start(filePath:string){
        // 开始解包
        // 获取配置
        let {config,mainPackage} = this.getConfig(fs.readFileSync(filePath));
        return {
            data:this.parseFile(config,fs.readFileSync(filePath)),
            config,
            mainPackage
        };
    }

    // 获取打包配置项
    static getConfig(content:Buffer = Buffer.from("")){
        // 获取配置
        let config = JSON.parse(content.slice(0,content.indexOf("\0")).toString());
        let mainPackage = config["mainPackage"];
        delete config["mainPackage"];
        Object.keys(config).forEach(e=>{
            config[e].filePath = path.join(e);
            config[e].scope = {
                start:Number(config[e].scope.split(",")[0])+content.indexOf("\0")+1,
                end:Number(config[e].scope.split(",")[1])+content.indexOf("\0")+1
            }
            if(path.join(e) !== e){
                config[path.join(e)] = config[e];
                delete config[e];
            }
        });
        return {
            config,
            mainPackage
        };
    }

    /**
     * 解析出每个配置项
     * @param {Object} config 
     * @param {Buffer} content 
     * @returns 
     */
    static parseFile(config:any,content:Buffer = Buffer.from("")){
        let fileMap = {};
        Object.keys(config).forEach(e=>{
            fileMap[e] = content.slice(config[e].scope.start,config[e].scope.end);
            if(fileMap[e].toString().includes("__2021.12.9 16:19__")){
                console.log(fileMap[e].toString())
                exit(0)
            }
        })
        return fileMap;
    }
    /**
     * 把打包文件还原
     */
    static reduction(filePath:string){
        filePath = path.resolve(filePath);
        let {data,config} = this.start(filePath);
        delete config["mainPackage"];
        Object.keys(config).forEach(e=>{
            // 创建父目录
            let supDir = path.join(path.dirname(filePath),path.parse(filePath).name,path.parse(e).dir);
            fs.mkdirSync(supDir,{recursive:true})
            // 写入文件
            if(config[e].guidePackage){
                data[e] = data[e].toString();
                // 对文件内容进行修复
                config[e].guidePackage.forEach((ee)=>{
                    let target = ee.split(">>>")[0];
                    let conversion = ee.split(">>>")[1];
                    data[e] = data[e].replace(new RegExp(`(?<=require\\(["'])${conversion}?(?=["']\\))`),target);
                })
            }
            fs.writeFileSync(path.join(supDir,path.basename(e)) ,data[e]);
            if(!config[e].md5){
                console.log("校验成功 successful",e)
            }else if(md5(data[e]) === config[e].md5){
                console.log("校验成功 successful",e)
            }else{
                console.log("md5校验失败",[e]);
                throw new Error("md5校验失败");
            }
        })
        console.log("解包完成")
    }

}